package com.yuedou.api.pay.wxpay;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.gson.Gson;
import com.yuedou.api.util.OkHttpClientUtil;
import com.yuedou.api.util.StringUtil;
import org.jdom2.JDOMException;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class WxAppPay {

    private String notify_Url;
    public String API_KEY;
    public String APPID;
    public String MCH_ID;
    private String secret;

    public WxAppPay(String notify_Url,String secret,String appid,String mech_id,String api_key){
        this.notify_Url = notify_Url;
        this.API_KEY = api_key;
        this.APPID = appid;
        this.MCH_ID = mech_id;
        this.secret = secret;
    }


    /**
     * 微信支付  统一下单
     * @param out_trade_no
     * @param totalAmount
     * @param description
     * @param requestIp
     * @return
     */
    public String weiXinPrePay(String out_trade_no, BigDecimal totalAmount, String description, String requestIp, String open_id,String attach) {
        String result = null;
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("appid", APPID);
        parameterMap.put("mch_id", MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("body", description);
        parameterMap.put("out_trade_no", out_trade_no);
        parameterMap.put("fee_type", "CNY");
        parameterMap.put("total_fee", StringUtil.yuanToCent(String.valueOf(totalAmount)));
        parameterMap.put("spbill_create_ip", requestIp);
        parameterMap.put("notify_url", notify_Url);
        parameterMap.put("trade_type", "JSAPI");
        parameterMap.put("openid", open_id);
        parameterMap.put("attach", attach);

        String sign = WXPayCommonUtil.createSign("UTF-8",API_KEY ,parameterMap);
        parameterMap.put("sign", sign);
        String requestXML = WXPayCommonUtil.getRequestXml(parameterMap);
        System.out.println(" 支付申请 requestXML: " + requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        String result_wx = WXPayCommonUtil.httpsRequest(requestUrl, "POST",requestXML);
        System.out.println("数据返回：" +result_wx);
        Map<String, String> map = null;
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            if(map != null){
                SortedMap<String, Object> finalpackage = new TreeMap<String, Object>();
                finalpackage.put("appId", APPID);
                String timeMillis = String.valueOf(System.currentTimeMillis() / 1000);
                finalpackage.put("timeStamp", timeMillis);
                finalpackage.put("nonceStr", randomString);
                finalpackage.put("package", "prepay_id=" + (map.containsKey("prepay_id") ? map.get("prepay_id"):""));
                finalpackage.put("signType", "MD5");
                sign = WXPayCommonUtil.createSign("UTF-8",API_KEY, finalpackage);

                Map<String,String> mapReturn = new HashMap<String, String>();
                mapReturn.put("nonceStr",randomString);
                mapReturn.put("timeStamp", timeMillis);
                mapReturn.put("prepay_id",map.containsKey("prepay_id") ? map.get("prepay_id"):"");
                mapReturn.put("package", "prepay_id=" + (map.containsKey("prepay_id") ? map.get("prepay_id"):""));
                mapReturn.put("paySign", sign);
                mapReturn.put("signType", "MD5");
                mapReturn.put("result_code",map.containsKey("result_code") ? map.get("result_code"):"");
                mapReturn.put("err_code",map.containsKey("err_code") ? map.get("err_code") : "");
                mapReturn.put("err_code_des",map.containsKey("err_code_des") ? map.get("err_code_des") : "");
                Gson gson = new Gson();
                result = gson.toJson(mapReturn);
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }



    /**
     * 微信支付  订单查询
     * @param out_trade_no
     * @return
     */
    public String weiXinOrderQuery(String out_trade_no) {
        String result = null;
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("appid", APPID);
        parameterMap.put("mch_id", MCH_ID);
        parameterMap.put("out_trade_no", out_trade_no);
        parameterMap.put("nonce_str", randomString);

        String sign = WXPayCommonUtil.createSign("UTF-8",API_KEY ,parameterMap);
        parameterMap.put("sign", sign);
        String requestXML = WXPayCommonUtil.getRequestXml(parameterMap);
        System.out.println(" 订单查询 请求数据: " + requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/pay/orderquery";
        String result_wx = WXPayCommonUtil.httpsRequest(requestUrl, "POST",requestXML);
        System.out.println(" 订单查询数据返回： " + result_wx);
        Map<String, String> map = null;
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            if(map != null){
//                String total_fee = map.containsKey("total_fee") ? map.get("total_fee"):"";
//                String transaction_id = map.containsKey("transaction_id") ? map.get("transaction_id"):"";
//                String attach = map.containsKey("attach") ? map.get("attach"):"";
//                String trade_state = map.containsKey("trade_state") ? map.get("trade_state"):"";
//                String result_code = map.containsKey("result_code") ? map.get("result_code"):"";
//
//
//                Map<String,String> mapReturn = new HashMap<>();
//                mapReturn.put("nonceStr",randomString);
//                mapReturn.put("timeStamp", timeMillis);
//                mapReturn.put("prepay_id",map.containsKey("prepay_id") ? map.get("prepay_id"):"");
//                mapReturn.put("paySign", sign);
//                mapReturn.put("result_code",map.containsKey("result_code") ? map.get("result_code"):"");
//                mapReturn.put("err_code",map.containsKey("err_code") ? map.get("err_code") : "");
//                mapReturn.put("err_code_des",map.containsKey("err_code_des") ? map.get("err_code_des") : "");
                Gson gson = new Gson();
                result = gson.toJson(map);
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 微信 退款   申请 接口
     * @param out_trade_no
     * @param totalAmount
     * @param refund_money
     * @param out_refund_no
     * @return
     */
    public String refundPayAPIStr(String out_trade_no,BigDecimal totalAmount, BigDecimal refund_money,String out_refund_no,String certPath){
        String result = "FAIL";
        JSONObject jsonResult = new JSONObject();
        jsonResult.set("code","FAIL");
        jsonResult.set("msg","提交失败");
        SortedMap<String, Object> parameterMap = new TreeMap<>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("appid", APPID);
        parameterMap.put("mch_id", MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("out_trade_no", out_trade_no);
        parameterMap.put("out_refund_no", out_refund_no);//订单总金额，单位为分，只能为整数

        BigDecimal total = totalAmount.multiply(new BigDecimal(100));
        BigDecimal refund_total = refund_money.multiply(new BigDecimal(100));
        DecimalFormat df = new DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total));//订单总金额，单位为分，只能为整数
        parameterMap.put("refund_fee", df.format(refund_total));//订单总金额，单位为分，只能为整数
        parameterMap.put("notify_url", notify_Url);//订单总金额，单位为分，只能为整数

        //计算签名
        String sign = WXPayCommonUtil.createSign("UTF-8", API_KEY, parameterMap);
        parameterMap.put("sign", sign);
        //拼接 xml文件
        String requestXML = WXPayCommonUtil.getRequestXml(parameterMap);
        System.out.println("requestXML: " + requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        //发起退款请求
        String result_wx = null;
        try {
            result_wx = WXPayCommonUtil.httpsRequestRefund(requestUrl,requestXML,MCH_ID,certPath);
            System.out.println("退款请求响应数据：" + result_wx);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, String> map = null;
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            if(map != null){
                String result_code = map.containsKey("result_code") ? map.get("result_code") : "FAIL";
                String err_code = map.get("err_code");
                String return_msg = map.containsKey("return_msg") ? map.get("return_msg") : "FAIL";
                String return_code = map.containsKey("return_code") ? map.get("return_code") : "FAIL";
                if(result_code.equals("SUCCESS")){//退款申请提交成功

                }else{

                }
                jsonResult.set("code",result_code);
                jsonResult.set("msg",err_code);
                jsonResult.set("return_code",return_code);
                jsonResult.set("return_msg",return_msg);
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return jsonResult.toString();
    }


    /**
     * 抖音的微信支付  预下单接口
     * @param out_order_no
     * @param totalAmount
     * @param subject
     * @return
     */
    public String weiXinPrePayDy(String out_order_no, BigDecimal totalAmount, String subject,String attach) {
        String result = null;
        SortedMap<String, Object> parameterMap = new TreeMap<>();
        parameterMap.put("app_id", APPID);
        parameterMap.put("out_order_no", out_order_no);
        parameterMap.put("total_amount", Integer.parseInt(StringUtil.yuanToCent(String.valueOf(totalAmount))));
        parameterMap.put("subject", subject);
        parameterMap.put("body", subject);
        parameterMap.put("valid_time", 60 * 15);//30分钟 （秒数） 订单过期时间(秒)
        parameterMap.put("cp_extra", attach);//开发者自定义字段，回调原样回传
        parameterMap.put("notify_url", notify_Url);

        String sign = WXPayCommonUtil.getDySign(parameterMap,API_KEY);

        parameterMap.put("sign", sign);
        String dataJson = JSONUtil.toJsonStr(parameterMap);
        System.out.println("dataJson: " + dataJson);
        String requestUrl = "https://developer.toutiao.com/api/apps/ecpay/v1/create_order";
        try {
            String result_wx = OkHttpClientUtil.getInstance().postJson(requestUrl, dataJson);
            System.out.println("数据返回：" + result_wx);
            JSONObject jsonObject = JSONUtil.parseObj(result_wx);
            result = JSONUtil.toJsonStr(jsonObject);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }


    /**
     * 微信支付  企业付款到零钱（提现）
     * @param partner_trade_no  付款订单号
     * @param pay_money  支付金额
     * @param openid   公众号openid
     * @param certPath  证书路径
     * @return
     */
    public Map<String, String> weixinChangePay(String partner_trade_no, BigDecimal pay_money,String openid,String certPath,String remark){
        Map<String, String> mapReturn = new HashMap<>();
        SortedMap<String, Object> parameterMap = new TreeMap<>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("mch_appid", APPID);
        parameterMap.put("mchid", MCH_ID);
        parameterMap.put("nonce_str", randomString.toUpperCase());
        parameterMap.put("partner_trade_no", partner_trade_no);//商户订单号，需保持唯一性
        parameterMap.put("openid", openid);//收款人的openid   是微信用户在公众号appid下的唯一用户标识
        parameterMap.put("check_name","NO_CHECK");
        BigDecimal pay_total = pay_money.multiply(new BigDecimal(100));
        DecimalFormat df = new DecimalFormat("0");
        parameterMap.put("amount", df.format(pay_total));//付款金额，单位为分
        parameterMap.put("desc", remark);//付款备注，必填。注意：备注中的敏感词会被转成字符*
        //计算签名
        String sign = WXPayCommonUtil.createSign("UTF-8",API_KEY, parameterMap);
        parameterMap.put("sign", sign.toUpperCase());
        //拼接 xml文件
        String requestXML = WXPayCommonUtil.getRequestXml1(parameterMap);
        System.out.println("requestXML: "+requestXML);
        mapReturn.put("pay_str",requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
        //发起付款到零钱请求
        String result_wx = null;
        try {
            result_wx = WXPayCommonUtil.httpsRequestRefund(requestUrl,requestXML,MCH_ID,certPath);
            mapReturn.put("reback_str",result_wx);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("付款到零钱请求响应数据：" + result_wx);
        Map<String, String> map = new HashMap<>();
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            mapReturn.put("result_code","");
            if(map != null){
                String return_code = map.get("return_code");
                String return_msg = map.get("return_msg");
                String result_code = map.get("result_code");
                String err_code_des = map.containsKey("err_code_des") ? map.get("err_code_des") : "";
                mapReturn.put("return_code",return_code);
                mapReturn.put("return_msg",return_msg);
                mapReturn.put("result_code",result_code);
                mapReturn.put("err_code_des",err_code_des);
                if(return_code.equals("SUCCESS")){  //付款到零钱申请提交成功

                }else{

                }
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return mapReturn;
    }

    /**
     * 微信 退款   申请 接口
     * @param out_trade_no
     * @param totalAmount
     * @param refund_money
     * @param out_refund_no
     * @return
     */
    public String refundPayAPI(String out_trade_no,BigDecimal totalAmount,BigDecimal refund_money,String out_refund_no,String certPath){
        String result = null;
        JSONObject jsonResult = new JSONObject();
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("appid", APPID);
        parameterMap.put("mch_id", MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("out_trade_no", out_trade_no);
        parameterMap.put("out_refund_no", out_refund_no);//订单总金额，单位为分，只能为整数

        BigDecimal total = totalAmount.multiply(new BigDecimal(100));
        BigDecimal refund_total = refund_money.multiply(new BigDecimal(100));
        DecimalFormat df = new DecimalFormat("0");
        parameterMap.put("total_fee", df.format(total));//订单总金额，单位为分，只能为整数
        parameterMap.put("refund_fee", df.format(refund_total));//订单总金额，单位为分，只能为整数
        parameterMap.put("notify_url", notify_Url);//订单总金额，单位为分，只能为整数

        //计算签名
        String sign = WXPayCommonUtil.createSign("UTF-8", API_KEY, parameterMap);
        parameterMap.put("sign", sign);
        //拼接 xml文件
        String requestXML = WXPayCommonUtil.getRequestXml(parameterMap);
        System.out.println("requestXML: " + requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        //发起退款请求
        String result_wx = null;
        try {
            result_wx = WXPayCommonUtil.httpsRequestRefund(requestUrl,requestXML,MCH_ID,certPath);
            System.out.println("退款请求响应数据：" + result_wx);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, String> map = null;
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            if(map != null){
                String result_code = map.containsKey("result_code") ? map.get("result_code") : "FAIL";
                String err_code = map.get("err_code");
                String return_msg = map.containsKey("return_msg") ? map.get("return_msg") : "FAIL";
                String return_code = map.containsKey("return_code") ? map.get("return_code") : "FAIL";
                if(result_code.equals("SUCCESS")){//退款申请提交成功

                }else{

                }
                jsonResult.set("code",result_code);
                jsonResult.set("msg",err_code);
                jsonResult.set("return_code",return_code);
                jsonResult.set("return_msg",return_msg);
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return jsonResult.toString();
    }

    /**
     * 微信 退款查询   接口
     * @param out_trade_no
     * @return
     */
    public String refundQueryAPI(String out_trade_no){
        String result = null;
        SortedMap<String, Object> parameterMap = new TreeMap<String, Object>();
        String randomString = WXPayCommonUtil.getRandomString(32);
        parameterMap.put("appid", APPID);
        parameterMap.put("mch_id", MCH_ID);
        parameterMap.put("nonce_str", randomString);
        parameterMap.put("out_trade_no", out_trade_no);

        //计算签名
        String sign = WXPayCommonUtil.createSign("UTF-8",API_KEY, parameterMap);
        parameterMap.put("sign", sign);
        //拼接 xml文件
        String requestXML = WXPayCommonUtil.getRequestXml(parameterMap);
        System.out.println("requestXML: "+requestXML);
        String requestUrl = "https://api.mch.weixin.qq.com/pay/refundquery";
        //发起退款请求
        String result_wx = WXPayCommonUtil.httpsRequest(requestUrl, "POST",requestXML);
        System.out.println("退款查询请求响应数据：" + result_wx);
        Map<String, String> map = null;
        try {
            map = WXPayCommonUtil.doXMLParse(result_wx);
            if(map != null){
                String result_code = map.get("result_code");
                if(result_code.equals("SUCCESS")){//退款申请提交成功

                }else{

                }
            }
        } catch (JDOMException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return result;
    }

}
